{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# DeepScalper for Algorithm Trading\n",
    "This tutorial is to demonstrate an example of using DeepScalper to do Algorithms Trading on the Bitcoin"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Set up Experinment Environment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting package metadata (current_repodata.json): done\n",
      "Solving environment: done\n",
      "\n",
      "\n",
      "==> WARNING: A newer version of conda exists. <==\n",
      "  current version: 4.10.1\n",
      "  latest version: 4.14.0\n",
      "\n",
      "Please update conda by running\n",
      "\n",
      "    $ conda update -n base -c defaults conda\n",
      "\n",
      "\n",
      "\n",
      "## Package Plan ##\n",
      "\n",
      "  environment location: /home/sunshuo/miniconda3/envs/FinRL\n",
      "\n",
      "  added / updated specs:\n",
      "    - cudatoolkit=11.3\n",
      "    - pytorch\n",
      "    - torchaudio\n",
      "    - torchvision\n",
      "\n",
      "\n",
      "The following packages will be downloaded:\n",
      "\n",
      "    package                    |            build\n",
      "    ---------------------------|-----------------\n",
      "    pytorch-1.12.1             |      py3.7_cpu_0        76.6 MB  pytorch\n",
      "    torchaudio-0.12.1          |         py37_cpu         6.0 MB  pytorch\n",
      "    torchvision-0.13.1         |         py37_cpu        24.5 MB  pytorch\n",
      "    ------------------------------------------------------------\n",
      "                                           Total:       107.1 MB\n",
      "\n",
      "The following packages will be UPDATED:\n",
      "\n",
      "  ca-certificates    conda-forge::ca-certificates-2022.6.1~ --> pkgs/main::ca-certificates-2022.07.19-h06a4308_0\n",
      "  cudatoolkit        conda-forge::cudatoolkit-11.0.3-h88f8~ --> pkgs/main::cudatoolkit-11.3.1-h2bc3f7f_2\n",
      "  openssl            conda-forge::openssl-1.1.1o-h166bdaf_0 --> pkgs/main::openssl-1.1.1q-h7f8727e_0\n",
      "  pytorch                                1.12.0-py3.7_cpu_0 --> 1.12.1-py3.7_cpu_0\n",
      "  torchaudio                                0.12.0-py37_cpu --> 0.12.1-py37_cpu\n",
      "  torchvision                               0.13.0-py37_cpu --> 0.13.1-py37_cpu\n",
      "\n",
      "The following packages will be SUPERSEDED by a higher-priority channel:\n",
      "\n",
      "  certifi            conda-forge::certifi-2022.6.15-py37h8~ --> pkgs/main::certifi-2022.6.15-py37h06a4308_0\n",
      "\n",
      "\n",
      "Proceed ([y]/n)? ^C\n",
      "\n",
      "CondaSystemExit: \n",
      "Operation aborted.  Exiting.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from IPython.display import clear_output\n",
    "import argparse\n",
    "import sys\n",
    "import numpy as np\n",
    "import torch\n",
    "from torch import nn\n",
    "import yaml\n",
    "import os\n",
    "import pandas as pd\n",
    "module_path = os.path.abspath(os.path.join('..'))\n",
    "sys.path.append(module_path)\n",
    "requirements_path=module_path+\"/requirements.txt\"\n",
    "print(requirements_path)\n",
    "command=\"pip install -r \"+requirements_path\n",
    "os.system(command)\n",
    "clear_output(wait=True)\n",
    "! conda install pytorch torchvision torchaudio cudatoolkit=11.3 -c pytorch\n",
    "clear_output(wait=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Download and Preprocess the Data\n",
    "The dataconfig part in TradeMaster is shared by all other parts, it is worth noticing that for algorithms trading, only the dataset BTC is supported.\n",
    "\n",
    "The following code will help to download the data in the folder [.data/data/BTC](https://github.com/qinmoelei/TradeMaster_reframe/tree/master/tutorial/data/data/BTC), where 4 files could be found: the whole data and train, valid and test data which will be used when we try to construct the RL environment for the agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from data.download_data import Dataconfig\n",
    "parser = argparse.ArgumentParser()\n",
    "\n",
    "parser.add_argument(\"--data_path\",\n",
    "                    type=str,\n",
    "                    default=\"./data/data/\",\n",
    "                    help=\"the path for storing the downloaded data\")\n",
    "#where we store the dataset\n",
    "parser.add_argument(\n",
    "    \"--output_config_path\",\n",
    "    type=str,\n",
    "    default=\"./config/output_config/data\",\n",
    "    help=\"the path for storing the generated config file for data\")\n",
    "# where we store the config file\n",
    "parser.add_argument(\n",
    "    \"--dataset\",\n",
    "    choices=[\"BTC\"],\n",
    "    default=\"BTC\",\n",
    "    help=\"the name of the dataset\",\n",
    ")\n",
    "parser.add_argument(\"--split_proportion\",\n",
    "                    type=list,\n",
    "                    default=[0.8, 0.1, 0.1],\n",
    "                    help=\"the split proportion for train, valid and test\")\n",
    "parser.add_argument(\n",
    "    \"--generate_config\",\n",
    "    type=bool,\n",
    "    default=False,\n",
    "    help=\n",
    "    \"determine whether to generate a yaml file to memorize the train valid and test'data's dict\"\n",
    ")\n",
    "parser.add_argument(\n",
    "    \"--input_config\",\n",
    "    type=bool,\n",
    "    default=False,\n",
    "    help=\n",
    "    \"determine whether to use a yaml file as the overall input of the Dataconfig, this is needed when have other format of dataset\"\n",
    ")\n",
    "\n",
    "parser.add_argument(\n",
    "    \"--input_config_path\",\n",
    "    type=str,\n",
    "    default=\"config/input_config/data/custom.yml\",\n",
    "    help=\n",
    "    \"determine the location of a yaml file used to initialize the Dataconfig Class\"\n",
    ")\n",
    "args = parser.parse_args(args=[])\n",
    "a = Dataconfig(args)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "the preprocessed data follows the following structure:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>tic</th>\n",
       "      <th>date</th>\n",
       "      <th>high</th>\n",
       "      <th>low</th>\n",
       "      <th>open</th>\n",
       "      <th>close</th>\n",
       "      <th>adjcp</th>\n",
       "      <th>zopen</th>\n",
       "      <th>zhigh</th>\n",
       "      <th>zlow</th>\n",
       "      <th>zadjcp</th>\n",
       "      <th>zclose</th>\n",
       "      <th>zd_5</th>\n",
       "      <th>zd_10</th>\n",
       "      <th>zd_15</th>\n",
       "      <th>zd_20</th>\n",
       "      <th>zd_25</th>\n",
       "      <th>zd_30</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>BTC</td>\n",
       "      <td>2013-04-29 23:59:59</td>\n",
       "      <td>147.488007</td>\n",
       "      <td>134.000000</td>\n",
       "      <td>134.444000</td>\n",
       "      <td>144.539993</td>\n",
       "      <td>144.539993</td>\n",
       "      <td>-0.069849</td>\n",
       "      <td>0.020396</td>\n",
       "      <td>-0.072921</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-0.038328</td>\n",
       "      <td>0.234762</td>\n",
       "      <td>0.029592</td>\n",
       "      <td>-0.012624</td>\n",
       "      <td>-0.053283</td>\n",
       "      <td>-0.066832</td>\n",
       "      <td>-0.066352</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>BTC</td>\n",
       "      <td>2013-04-30 23:59:59</td>\n",
       "      <td>146.929993</td>\n",
       "      <td>134.050003</td>\n",
       "      <td>144.000000</td>\n",
       "      <td>139.000000</td>\n",
       "      <td>139.000000</td>\n",
       "      <td>0.035971</td>\n",
       "      <td>0.057050</td>\n",
       "      <td>-0.035611</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-0.038328</td>\n",
       "      <td>0.234762</td>\n",
       "      <td>0.029592</td>\n",
       "      <td>-0.012624</td>\n",
       "      <td>-0.053283</td>\n",
       "      <td>-0.066832</td>\n",
       "      <td>-0.066352</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>BTC</td>\n",
       "      <td>2013-05-01 23:59:59</td>\n",
       "      <td>139.889999</td>\n",
       "      <td>107.720001</td>\n",
       "      <td>139.000000</td>\n",
       "      <td>116.989998</td>\n",
       "      <td>116.989998</td>\n",
       "      <td>0.188136</td>\n",
       "      <td>0.195743</td>\n",
       "      <td>-0.079238</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-0.158345</td>\n",
       "      <td>0.234762</td>\n",
       "      <td>0.029592</td>\n",
       "      <td>-0.012624</td>\n",
       "      <td>-0.053283</td>\n",
       "      <td>-0.066832</td>\n",
       "      <td>-0.066352</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>BTC</td>\n",
       "      <td>2013-05-02 23:59:59</td>\n",
       "      <td>125.599998</td>\n",
       "      <td>92.281898</td>\n",
       "      <td>116.379997</td>\n",
       "      <td>105.209999</td>\n",
       "      <td>105.209999</td>\n",
       "      <td>0.106169</td>\n",
       "      <td>0.193803</td>\n",
       "      <td>-0.122879</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-0.100692</td>\n",
       "      <td>0.234762</td>\n",
       "      <td>0.029592</td>\n",
       "      <td>-0.012624</td>\n",
       "      <td>-0.053283</td>\n",
       "      <td>-0.066832</td>\n",
       "      <td>-0.066352</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>BTC</td>\n",
       "      <td>2013-05-03 23:59:59</td>\n",
       "      <td>108.127998</td>\n",
       "      <td>79.099998</td>\n",
       "      <td>106.250000</td>\n",
       "      <td>97.750000</td>\n",
       "      <td>97.750000</td>\n",
       "      <td>0.086957</td>\n",
       "      <td>0.106169</td>\n",
       "      <td>-0.190793</td>\n",
       "      <td>0.0</td>\n",
       "      <td>-0.070906</td>\n",
       "      <td>0.234762</td>\n",
       "      <td>0.029592</td>\n",
       "      <td>-0.012624</td>\n",
       "      <td>-0.053283</td>\n",
       "      <td>-0.066832</td>\n",
       "      <td>-0.066352</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   tic                 date        high         low        open       close  \\\n",
       "0  BTC  2013-04-29 23:59:59  147.488007  134.000000  134.444000  144.539993   \n",
       "1  BTC  2013-04-30 23:59:59  146.929993  134.050003  144.000000  139.000000   \n",
       "2  BTC  2013-05-01 23:59:59  139.889999  107.720001  139.000000  116.989998   \n",
       "3  BTC  2013-05-02 23:59:59  125.599998   92.281898  116.379997  105.209999   \n",
       "4  BTC  2013-05-03 23:59:59  108.127998   79.099998  106.250000   97.750000   \n",
       "\n",
       "        adjcp     zopen     zhigh      zlow  zadjcp    zclose      zd_5  \\\n",
       "0  144.539993 -0.069849  0.020396 -0.072921     0.0 -0.038328  0.234762   \n",
       "1  139.000000  0.035971  0.057050 -0.035611     0.0 -0.038328  0.234762   \n",
       "2  116.989998  0.188136  0.195743 -0.079238     0.0 -0.158345  0.234762   \n",
       "3  105.209999  0.106169  0.193803 -0.122879     0.0 -0.100692  0.234762   \n",
       "4   97.750000  0.086957  0.106169 -0.190793     0.0 -0.070906  0.234762   \n",
       "\n",
       "      zd_10     zd_15     zd_20     zd_25     zd_30  \n",
       "0  0.029592 -0.012624 -0.053283 -0.066832 -0.066352  \n",
       "1  0.029592 -0.012624 -0.053283 -0.066832 -0.066352  \n",
       "2  0.029592 -0.012624 -0.053283 -0.066832 -0.066352  \n",
       "3  0.029592 -0.012624 -0.053283 -0.066832 -0.066352  \n",
       "4  0.029592 -0.012624 -0.053283 -0.066832 -0.066352  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data=pd.read_csv(\"data/data/BTC/BTC.csv\",index_col=0)\n",
    "data.head(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "the index column are corresponding to date one by one and in the algorithm trading case, there is only 1 tic. Besides OHLC, the data also has some normalized features"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## RL Enviornment Construction, Agent Training, Model Picking and Testing\n",
    "For the simplicity, we use the yaml file to store the configuration for the RL environment construction, which can be found [here](https://github.com/qinmoelei/TradeMaster_reframe/tree/master/tutorial/config/input_config/env/AT/DeepScalper)\n",
    "but first, let us import the package we might use"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from env.AT.AT import TradingEnv\n",
    "from agent.DeepScalper.model import Net\n",
    "from agent.DeepScalper.dqn import DQN"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The rest parameter of the algorithms could be modified through the args displayed followed.\n",
    "\n",
    "You can find the trained model and test result [here](https://github.com/qinmoelei/TradeMaster_reframe/tree/master/tutorial/result/AT)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "parser = argparse.ArgumentParser()\n",
    "parser.add_argument(\"--hidden_nodes\",\n",
    "                    type=int,\n",
    "                    default=256,\n",
    "                    help=\"the number of transcation we learn at a time\")\n",
    "parser.add_argument(\"--batch_size\",\n",
    "                    type=int,\n",
    "                    default=32,\n",
    "                    help=\"the number of transcation we learn at a time\")\n",
    "parser.add_argument(\"--lr\", type=float, default=1e-3, help=\"the learning rate\")\n",
    "parser.add_argument(\"--epsilon\",\n",
    "                    type=float,\n",
    "                    default=0.9,\n",
    "                    help=\"the learning rate\")\n",
    "parser.add_argument(\"--gamma\",\n",
    "                    type=float,\n",
    "                    default=0.9,\n",
    "                    help=\"the learning rate\")\n",
    "parser.add_argument(\n",
    "    \"--target_freq\",\n",
    "    type=int,\n",
    "    default=50,\n",
    "    help=\"the number of updates before the eval could be as same as the target\"\n",
    ")\n",
    "parser.add_argument(\n",
    "    \"--memory_capacity\",\n",
    "    type=int,\n",
    "    default=2000,\n",
    "    help=\"the number of updates before the eval could be as same as the target\"\n",
    ")\n",
    "parser.add_argument(\"--train_env_config\",\n",
    "                    type=str,\n",
    "                    default=\"config/input_config/env/AT/DeepScalper/train.yml\",\n",
    "                    help=\"the dict for storing env config\")\n",
    "parser.add_argument(\"--valid_env_config\",\n",
    "                    type=str,\n",
    "                    default=\"config/input_config/env/AT/DeepScalper/valid.yml\",\n",
    "                    help=\"the dict for storing env config\")\n",
    "parser.add_argument(\"--test_env_config\",\n",
    "                    type=str,\n",
    "                    default=\"config/input_config/env/AT/DeepScalper/test.yml\",\n",
    "                    help=\"the dict for storing env config\")\n",
    "parser.add_argument(\n",
    "    \"--future_loss_weights\",\n",
    "    type=float,\n",
    "    default=0.2,\n",
    "    help=\"the weights for future loss\",\n",
    ")\n",
    "parser.add_argument(\n",
    "    \"--model_path\",\n",
    "    type=str,\n",
    "    default=\"result/AT/trained_model\",\n",
    "    help=\"the path for storing the trained model\",\n",
    ")\n",
    "parser.add_argument(\n",
    "    \"--result_path\",\n",
    "    type=str,\n",
    "    default=\"result/AT/test_result\",\n",
    "    help=\"the path for storing the test result\",\n",
    ")\n",
    "args = parser.parse_args(args=[])\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "=================================\n",
      "the profit margin is 225.332916000391 %\n",
      "the sharpe ratio is 0.8607794104103924\n",
      "the Volatility is 15405.353796230673\n",
      "the max drawdown is 0.8349657199744575\n",
      "the Calmar Ratio is 269987.60271368525\n",
      "the Sortino Ratio is 1.0943025116967398\n",
      "=================================\n"
     ]
    }
   ],
   "source": [
    "def build_agent():\n",
    "    a = DQN(args)\n",
    "    return a\n",
    "\n",
    "\n",
    "def experiment(a: DQN):\n",
    "    a.train_with_valid(10)\n",
    "    clear_output(wait=True)\n",
    "    a.test()\n",
    "\n",
    "\n",
    "def main():\n",
    "    a = build_agent()\n",
    "    experiment(a)\n",
    "\n",
    "main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here is the process:\n",
    "\n",
    "We trained model on the train environment for 20 epochs, then when each epoch ends, we use the mdoel to do trading on the valid environment. We use sharpe-ratio as the indicator and choose the best model among 20 models in the valid environment and use the model to do trading in the test environment\n",
    "\n",
    "Here is what the test result look like:\n",
    "It contains the total assets and daily return.The difference lies in the transcation fee."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>daily_return</th>\n",
       "      <th>total assets</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>100000.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>116.113553</td>\n",
       "      <td>100105.422024</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>355.907811</td>\n",
       "      <td>100450.522076</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>-77.744929</td>\n",
       "      <td>100361.791257</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>-17.616443</td>\n",
       "      <td>100333.214864</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   daily_return   total assets\n",
       "0      0.000000  100000.000000\n",
       "1    116.113553  100105.422024\n",
       "2    355.907811  100450.522076\n",
       "3    -77.744929  100361.791257\n",
       "4    -17.616443  100333.214864"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "test_result=pd.read_csv(\"result/AT/test_result/result.csv\",index_col=0)\n",
    "test_result.head(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "from matplotlib import pyplot as plt\n",
    "x = range(289)\n",
    "y = test_result[\"total assets\"].tolist()\n",
    "plt.plot(x, y)  \n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.7.11 ('FinRL')",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.11"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "05c7ecc4e09568b16608f47442989c4eaf2bc45e71bc9e50b36593a814f6f101"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
